package sui.template
{
    import sui.utils.StringUtil;

    //够贱表达树
    public class ExpressionFactory
    {
        public static function create(str:String, caller:Function = null):IExpression
        {
            var i:int = str.lastIndexOf("|");
            //分解modifier
            if (i != -1)
            {
                return createModifier(str.substr(i + 1), create(str.substr(0, i)));
            }
            //优先级最低的开始找
            var arr:Array;
            //divide
            arr = str.split("%");
            if (arr.length > 1)
            {
                return createMathExp(arr, MathExp.MOD)
            }
            //add
            arr = str.split("+");
            if (arr.length > 1)
            {
                return createMathExp(arr, MathExp.ADD)
            }
            //substract
            arr = str.split("-");
            if (arr.length > 1)
            {
                return createMathExp(arr, MathExp.SUBSTRACT)
            }
            //multiply
            arr = str.split("*");
            if (arr.length > 1)
            {
                return createMathExp(arr, MathExp.MULTIPLY)
            }
            //divide
            arr = str.split("/");
            if (arr.length > 1)
            {
                return createMathExp(arr, MathExp.DIVIDE)
            }

            str = StringUtil.trim(str);

            if (str.length == 0)
            {
                return new InstantExp(0);
            }
            var num:Number;
            if (!isNaN(num = Number(str)))
            {
                if (caller != null && !isNaN(parseInt(str)))
                {
                    return new IndexExp(num);
                }
                return new InstantExp(num);
            }
            if (str.charAt(0) == "#")
            {
                return new ConstExp(str.substr(1));
            }
            if (str.charAt(0) == "$")
            {
                return new VariableExp(str.substr(1));
            }
            return new NullExp;
        }

        private static function createMathExp(expStrArr:Array, operator:int):MathExp
        {
            var expArr:Array = [];
            for each (var expStr:String in expStrArr)
            {
                expArr.push(create(expStr))
            }
            return new MathExp(expArr, operator);
        }

        private static function createModifier(str:String, exp:IExpression):IExpression
        {
            return exp;
        }
    }
}
